package utils.time
{
	import flash.display.Shape;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Dictionary;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	

	public class TimerManage
	{
		private static var Instance:TimerManage;
		private var m_SecondTimer:Timer;
		private var m_NotifierList:Vector.<IAddedFrame>;
		private var m_DelayCallList:Vector.<DelayCallInfo>;
		private var m_Counter:int;
		private var m_FrameTimer:Shape;
		
		private var m_CDList:Vector.<CDTimeInfo>;
		public function TimerManage( TEMP:Temp )
		{
			m_NotifierList = new Vector.<IAddedFrame>();
			m_DelayCallList = new Vector.<DelayCallInfo>();
			m_CDList = new Vector.<CDTimeInfo>();
			m_Counter = 0;
			Start();
		}
		public function register( fun:IAddedFrame ):void
		{
			m_NotifierList.push( fun );
		}
		public function unRegister( fun:IAddedFrame ):void
		{
			var index:int = m_NotifierList.indexOf( fun );
			if( index != -1 )
			{
				m_NotifierList.splice( index,1 );
			}
		}
		public static function getInstance():TimerManage
		{
			if( Instance == null )
			{
				Instance = new TimerManage( new Temp() );
			}
			return Instance;
		}
		
		/**
		 * 注册CD时间 
		 * @param id	唯一标识
		 * @param time	cd时间,以毫秒为单位。
		 * 
		 */		
		public function appCDTime( id:int,time:int ):void
		{
			m_CDList.push( new CDTimeInfo( id,time ) );
		}
		/**
		 * 获取CD时间 
		 * @param id	标识
		 * @return 		当前剩下的CD时间，为0则没有该ID的信息
		 * 
		 */
		public function getCDTime( id:int ):int
		{
			for( var i:int = 0;i < m_CDList.length;i++ )
			{
				if( m_CDList[i].ParentID == id )
				{
					var currTime:uint = getTimer();
					return m_CDList[i].getLastCDTime(currTime);
				}
			}
			return 0;
		}
		
		/**
		 * 添加延迟调用 
		 * @param delay		延迟时间，为0表示无限
		 * @param fun		结束调用
		 * @param params	结束调用参数
		 * @param timeFun	每秒调用
		 * @return 			此次延迟的ID
		 * 
		 */		
		public function appDelayCall( delay:int,fun:Function,params:Object,timeFun:Function = null ):int
		{
			m_Counter++;
			var info:DelayCallInfo = new DelayCallInfo( m_Counter,delay,fun,params,timeFun );
			m_DelayCallList.push( info );
			return m_Counter;
		}

		public function delDelayCall( id:int ):void
		{
			var i:int,len:int;
			len = m_DelayCallList.length;
			for( i = 0;i < len;i++ )
			{
				if( m_DelayCallList[i].ID == id )
				{
					m_DelayCallList[i].destroy();
					m_DelayCallList[i] = null;
					m_DelayCallList.splice( i,1 );
					return;
				}
			}
		}
		
		private function Start():void
		{
			if( m_SecondTimer == null )
			{
				m_SecondTimer = new Timer( 1000,0 );
				m_SecondTimer.addEventListener( TimerEvent.TIMER,onEnterSecond,false,0,true );
				m_SecondTimer.start();
			}
			if( m_FrameTimer == null )
			{
				m_FrameTimer = new Shape();
				m_FrameTimer.addEventListener(Event.ENTER_FRAME,onEnterFrame,false,0,true );
			}
		}
		private function onEnterSecond(evt:TimerEvent ):void
		{
			var i:int;
			var currTime:uint = getTimer();
			for( i = 0;i < m_CDList.length;i++ )
			{
				if( m_CDList[i].getLastCDTime(currTime) == 0 )
				{
					m_CDList.splice( i--,1);
				}
			}
			
			for( i = 0;i < m_DelayCallList.length;i++ )
			{
				var item:DelayCallInfo = m_DelayCallList[i];
				if( item.Delay > 0 && currTime >= item.EndTime )
				{
					if( item.Params != null )
						item.CallFun( item.Params );
					else
						item.CallFun();
					item.destroy();
					m_DelayCallList[i] = null;
					m_DelayCallList.splice( i,1 );
					i--;
				}
				else
				{
					var currCounter:int = ( item.EndTime - currTime ) / 1000;
					if( item.CurrentCount != currCounter )
					{
						item.CurrentCount = currCounter;
						if( item.TimerFun != null )
						{
							item.TimerFun();
						}
					}
				}
			}
		}
		private function onEnterFrame( evt:Event ):void
		{
			if( m_NotifierList.length > 0 )
			{
				for( var i:int = 0;i < m_NotifierList.length;i++ )
				{
					if( m_NotifierList[i] )
					{
						m_NotifierList[i].onEnterFrame();
					}
				}
			}
		}
		
		public function destroy():void
		{
			if( m_SecondTimer )
			{
				m_SecondTimer.removeEventListener(TimerEvent.TIMER,onEnterSecond);
				m_SecondTimer.stop();
				m_SecondTimer = null;
			}
			if( m_FrameTimer )
			{
				m_FrameTimer.removeEventListener(Event.ENTER_FRAME,onEnterFrame );
				m_FrameTimer = null;
			}
			Instance = null;
			m_NotifierList = null;
			m_DelayCallList = null;
		}
	}
}
import flash.utils.getTimer;
class DelayCallInfo
{
	public var Delay:int;
	public var CallFun:Function;
	public var Params:Object;
	public var EndTime:uint;
	public var ID:int;
	public var TimerFun:Function;
	public var CurrentCount:int;
	public function DelayCallInfo( id:int,delay:int,call:Function,params:Object,timeFun:Function )
	{
		ID = id;
		Delay = delay;
		CallFun = call;
		Params = params;
		TimerFun = timeFun;
		EndTime = getTimer() + delay * 1000;
		CurrentCount = 0;
	}
	public function destroy():void
	{
		CallFun = null;
		Params = null;
	}
}
class CDTimeInfo
{
	public var ParentID:int;
	public var CDTime:int;
	private var StartTime:uint;
	public function CDTimeInfo( id:int,time:int )
	{
		StartTime = getTimer();
		ParentID = id;
		CDTime = time;
	}
	public function getLastCDTime( currTime:uint ):int
	{
		var result:int = CDTime - currTime + StartTime;
		if( result < 0 )
			result = 0;
		return result;
	}
	
}
class Temp
{
	
}